package com.illtamer.infinite.sillage.service;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.illtamer.infinite.sillage.mapper.CommentMapper;
import com.illtamer.infinite.sillage.pojo.Comment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

@Service
public class CommentService extends BaseMapperService<Comment> {

    private static final Comment EMPTY_PARENT_COMMENT = new Comment();

    @Autowired
    public CommentService(BaseMapper<Comment> mapper) {
        super(mapper);
    }

    /**
     * 获取顶级评论
     * */
    public List<Comment> listTopCommentByBlogId(Integer blogId) {
        return doListCommentByBlogId(((CommentMapper) mapper).listTopCommentByBlogId(blogId));
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean saveComment(Comment comment) {
        Integer parentId = Optional.of(comment.getParentComment()).orElseGet(() -> {
            comment.setParentComment(EMPTY_PARENT_COMMENT);
            return EMPTY_PARENT_COMMENT;
        }).getId();
        if (parentId != null)
            Assert.notNull(mapper.selectById(parentId));
        return mapper.insert(comment) > 0;
    }

    /**
     * 扁平化评论处理，n维 -> 2维
     * */
    private static List<Comment> doListCommentByBlogId(List<Comment> comments) {
        List<Comment> topComments = new LinkedList<>();
        for (Comment top : comments) {
            List<Comment> resultSon = new LinkedList<>();
            recursion(top, resultSon);
            // 清除2+深度的子评论
            resultSon.forEach(son -> son.setSonComment(null));
            top.setSonComment(resultSon);
            topComments.add(top);
        }
        return topComments;
    }

    private static void recursion(Comment topComment, List<Comment> resultSon) {
        if (topComment.getSonComment().isEmpty()) return;
        for (Comment son : topComment.getSonComment()) {
            resultSon.add(son);
            recursion(son, resultSon);
        }
    }

}
